<template>
    <div id="map" style="height: 100%;width:100%;border: 1px;"></div>
</template>
 
<script>
import "ol/ol.css";
import Map from "ol/Map";
import View from "ol/View";
import XYZ from "ol/source/XYZ";
import Tile from "ol/layer/Tile";
import TileLayer from "ol/layer/Tile";
import {tile as loadingstrategyTile } from 'ol/loadingstrategy';
import { createXYZ } from "ol/tilegrid";
import OSM from "ol/source/OSM";
import Vector from "ol/layer/Vector"
import { Vector as VectorSource } from "ol/source";
import Point from "ol/geom/Point";
import Feature from "ol/Feature";
import { createStringXY } from "ol/coordinate"
import { FullScreen, defaults as defaultControls, MousePosition } from "ol/control";
import { Style, Icon, Circle, Stroke, Fill, Text } from "ol/style";
import pointData from "./pointData"
import axios from "axios";
 
// 聚合图标缓存，避免重复创建
var styleCache = [];
export default {
  name: "pgisMap",
  data() {
    return {
      map: null, // 地图对象
      vectorSource: null, // 点位数据源
      vectorTile: null, // 点位数据图层
      timer: null,
      curZoom: 12,
      resolutionChange: false,
    };
  },
  mounted() {
    this.initMap();
  },
  methods:{
    initMap() {
      this.map = new Map({
        layers: [
          new TileLayer({
            wrapX: false, // 是否水平包装世界。设为时false，只会渲染一个世界
            source: new OSM()
          }),
        ],
        controls: defaultControls({}).extend([
              new MousePosition({
                coordinateFormat: createStringXY(5), //保留5位小数
                projection: "EPSG:4326"
            }),
          ]),
        target: "map",
        view: new View({
          zoom: 12,
          maxZoom: 15,
          center: [113.05642461656782, 23.6758880181949], //[116.63178, 23.64661],
          projection: "EPSG:4326", // EPSG:4326
        }),
      });
      this.curZoom = this.map.getView().getZoom().toFixed(0)
      // 监听地图分辨率变化事件
      this.map.getView().on("change:resolution", () =>{   
        this.resolutionChange = true             
        if (this.timer !== null) {
            clearTimeout(this.timer);
        }
        this.timer = setTimeout(() => {
            this.vectorSource.clear();
            this.curZoom = this.map.getView().getZoom().toFixed(0);
            this.resolutionChange = false
            this.addPointLayer(); // 地图分辨率变成完成后，重新请求渲染视野数据
        }, 35);
      })
      this.addPointLayer(); // 地图分辨率变成完成后，重新请求渲染视野数据
    },
    // 地图点位数据加载
    addPointLayer() {
      console.log("addPointLayer");
      this.vectorSource = new VectorSource({
          loader: (extent, resolution, projection) =>{
              //控制缩放结束前不发送请求
              if (this.resolutionChange)
              return false;
              // 此处loader自动请求后台数据，由于需要模拟数据，因为把请求注释。接口返回的实际，用pointData进行模拟
              // axios({
              //   method: "post",
              //   timeout: 1000,
              //   url: "http://192.168.30.10:8907/vector/tile",
              //   // params表示当前视野范围，把当前视野作为参数，传递给后台进行查询
              //   params: {
              //     minX: extent[0],
              //     minY: extent[1],
              //     maxX: extent[2],
              //     maxY: extent[3]
              //   },
              // }).then((res) => {
              //   console.log(res)
              // })

              // 接口返回成功以后，里面调用的方法=======start=======
              var z = Number(this.map.getView().getZoom().toFixed(0))
              let rsp = pointData[z]; 
              if (z == this.curZoom) {
                  var count = rsp.data.length
                  console.log("count="+count)
                  if(!count) {
                      return false
                  }
                  var features = new Array(count)
                  for (var i = 0; i < count; ++i) {
                      var coordinates = [Number(rsp.data[i].gpsX), Number(rsp.data[i].gpsY)]
                      let featureAttr = Object.assign({
                          geometry: new Point(coordinates),
                          data: rsp.data[i]
                      })
                      features[i] = new Feature(featureAttr);
                      features[i].setId(featureAttr.data.channel_ids)
                  }
                  this.vectorSource.addFeatures(features);
              }
          },
          strategy: loadingstrategyTile(
              createXYZ({
                  tileSize: 512,
              })
          )
      });
      this.vectorTile = new Vector({                             
        // 此处预留按照图层名称进行渲染的入口，先写死图层名称为"layerName"，   
        style: feature => this.setClusterStyle(feature),   
        source: this.vectorSource
      })
      this.map.addLayer(this.vectorTile) 
    },
    // 设置聚合数据源样式
    setClusterStyle(feature) {
      let featureData = feature.get('data')
      if(JSON.stringify(featureData) == "{}"){
          console.log('设备数据源为空')
          return false
      }
      let count = featureData.count || 1          
      // 1-15层用count为1都显示聚合图标，16层及后面就显示正常图标（demo效果，暂未实现）。
      if (styleCache[count] == undefined) {
          styleCache[count] = new Style({
              image: new Circle({
                  radius: 16,
                  stroke: new Stroke({
                      color: '#fff',
                  }),
                  fill: new Fill({
                      color: 'rgba(97,134,236,0.9)'
                  })
              }),
              text: new Text({
                  font: '12px sans-serif',
                  text: ''+ count,
                  fill: new Fill({
                      color: '#fff',
                  }),
              })
          })
      }                               
      return styleCache[count] 
    },
  }
};
</script>